package com.cloud.phone.vpn

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.content.pm.PackageManager
import android.net.VpnService
import android.os.Build
import android.os.ParcelFileDescriptor
import com.cloud.phone.R
import com.cloud.phone.constants.Constants
import com.cloud.phone.utils.ProxyUtils
import engine.Engine
import engine.Key
import java.util.concurrent.Executors

class MyVpnService : VpnService() {
    // private static final String HTTP = "l6W1sjwclS:80766829@154.200.18.18:6001"; // Your SOCKS5 server
    // private static final String SHADOWSOCKS = "https://s1.trojanflare.one/clashx/01593513-f46d-44a2-bacd-dd8066dcb104"; // Your SOCKS5 server
    //private static final String SOCKS5 = "socks5://l6W1sjwclS:80766829@154.200.18.18:6001"; // Your SOCKS5 server
    // You could spin up a local SOCK5 server on your workstation with:
    // ssh -ND "*:8080" -q -C -N <username>@<remote-host>
    private val executors = Executors.newFixedThreadPool(1)
    private var tun: ParcelFileDescriptor? = null
    override fun onCreate() {
        super.onCreate()
        if (tun == null) {
            try {
                val builder: Builder = Builder()
                    .addAddress(Constants.ADDRESS, 24)
                    .addRoute(Constants.ROUTE, 0)
                    .addDnsServer(Constants.DNS)
                    .addDisallowedApplication("com.cloud.phone")

                // let DNS queries bypass VPN if SOCKS server does not support UDP bind
                ProxyUtils.addRoutesExcept(builder, Constants.DNS, 32)
                tun = builder.establish()
                val key = Key()
                key.mark = 0
                key.mtu = 0
                key.device = "fd://" + tun?.fd
                key.setInterface("")
                key.logLevel = "debug"
                key.proxy = Constants.PROXY_SOCKS_URL
                key.restAPI = ""
                key.tcpSendBufferSize = ""
                key.tcpReceiveBufferSize = ""
                key.tcpModerateReceiveBuffer = false
                Engine.insert(key)
                executors?.submit { Engine.start() }
            } catch (e: PackageManager.NameNotFoundException) {
                throw RuntimeException(e)
            }
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        updateForegroundNotification()
        return START_STICKY
    }

    private fun updateForegroundNotification() {
        val vpnChannelId = "cloudphone"
        val mNotificationManager = getSystemService(
            NOTIFICATION_SERVICE
        ) as NotificationManager
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                mNotificationManager.createNotificationChannel(
                    NotificationChannel(
                        vpnChannelId, vpnChannelId,
                        NotificationManager.IMPORTANCE_DEFAULT
                    )
                )
                startForeground(
                    1, Notification.Builder(this, vpnChannelId)
                        .setSmallIcon(R.drawable.ic_launcher_background)
                        // .setContentText(getString(message))
                        //  .setContentIntent(mConfigureIntent)
                        .build()
                )
            }
        }
    }

    private fun disconnect() {
        Engine.stop()
        executors?.shutdownNow()
    }

    override fun onUnbind(intent: Intent?): Boolean {
        return super.onUnbind(intent)
    }

    override fun onDestroy() {
        super.onDestroy()
        executors?.shutdownNow()
    }
}
